package dgut.party.business.security.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import dgut.party.business.entity.base.Account;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter {
  private AuthenticationManager authenticationManager;

  public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "username";
  public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "password";

//	private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;
//	private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY;
//	private boolean postOnly = true;

  public JWTLoginFilter(AuthenticationManager authenticationManager) {
    super(new AntPathRequestMatcher("/login", "POST"));
    this.authenticationManager = authenticationManager;
  }

  @Override
  public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
    throws AuthenticationException, IOException, ServletException {
    try {
      Account user = new ObjectMapper().readValue(request.getInputStream(), Account.class);

      return authenticationManager.authenticate(
        new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword(),
          new ArrayList<>()));
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }

  @Override
  protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
                                          FilterChain chain, Authentication authResult) throws IOException, ServletException {
    // 赋权
    Map<String, Object> map = new HashMap<>();
    List<String> s = new ArrayList<>();
    authResult.getAuthorities().forEach((child) -> {
      s.add(child.getAuthority());
    });
    map.put("authorities", s.toArray());
    String token = Jwts.builder().setClaims(map)
      .setSubject(
        ((org.springframework.security.core.userdetails.User) authResult.getPrincipal())
          .getUsername())
      .setExpiration(new Date(System.currentTimeMillis() + 60 * 60 * 24 * 7 * 1000))// 有效期7天
      .signWith(SignatureAlgorithm.HS512, "MyJwtSecret").compact();
    // 生成认证请求头
    response.addHeader("Authorization", "Bearer " + token);
    response.getOutputStream().print("{\"token\":\"Bearer " + token + "\"}");
  }

  @Override
  protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
                                            AuthenticationException failed) throws IOException, ServletException {
    super.unsuccessfulAuthentication(request, response, failed);
    System.out.println("登录认证失败:" + failed.getMessage());
  }

}
